package cn.lhjl.day09.note;
/*
*
* 反射：将一个类的各个组成部分封装成其他对象，这些对象又作为成员变量构成了class类对象
*
*获取某个类在内存中对应的class类对象：
* 方法1：类名.class  虚拟机用类加载器将这个类加载进内存（前提是这个类还没被加载），不做类的初始化（例如静态代码块没
* 有被执行），返回Class类对象
* 方法2：Class.forName("包名.类名") 装载类，静态初始化这个类（例如静态代码块被执行），返回Class类对象
* 方法3：对象名.getClass()，对类进行静态初始化、非静态初始化，返回Class类对象。
*
* 结论：同一个字节码文件(.class文件)在一次程序运行过程中，只会被加载一次，不论哪种方式获取的Class对象都相同
*
* Class对象功能
* 获取：
* 1.获取成员变量们
* Fied[] getFields()
* Field getField(String name)获取的是指定名称的成员对应的对象
*
* Field[] geDeclaredFields()
* Field getDeclaredField(String name)
*
* 关于Field，它有方法来获取值和赋值，分别是 Object get(Object obj)和 void set(Object obj,Object value)
* 相比getter和setter方法，在参数上它们需要传入一个对象，因为要确定成员和对象。
*
*
* 2.获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
*
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
*
* 类<?>相当于：String.class
* 得到constructor后，用它调用newInstance来创建对象。对于无参构造函数，可以直接用personClass.new
* Instance来创建对象。同样要用私有构造器，需要用setAccessible(true)方法声明忽略修饰符的安全检查
*
* 3.获取成员方法们：
* Method[] getMethods()
* Method getMethod(String name,类<?>...parameterTypes)
*
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name,类<?>...parameterTypes)
*
* 例如得到Person的类对象personClass后，我们可以用personClass调用getName("setName",String.class)
* 来得到void getName(String name)这个方法的对象getName_method,也就是用方法名和方法参数来确定
* 要获取的方法对象。得到了方法对象后，要想执行它，我们需要调用它的invoke方法，
* Object invoke(Object obj,Object...args),obj是传入的对象，args是参数数组（这样写可变）。
* 要想获取一个方法对象对应的方法名可以用它调用String getName()
* 4.获取类名
* String getName()
* 想获取一个类对象对应的全类名，可以用类对象调用getName。
*
* 5.使用反射案例：
* 实现一个"框架",在不改变程序任何代码的情况下，创建任意类的对象，并执行其中的方法。
* 需要用到：1.配置文件。2.反射。
* 步骤：1.将需要创建的对象的全类名和要执行的方法写在配置文件中。
*      2.在程序中加载配置文件。
*      3.利用反射来加载类文件进内存
*      4.创建对象
*      5.执行方法
* 关注配置文件读数据的方法：创建.properties文件在src目录下，得到主类的构造器：Test.class.getClassLoader
* 然后用构造器来获取.properties文件的字节流。把字节流传给Properties类型集合。用这个集合获取想知道的变量的值（用键找值）
*
* 小结：知道字符串className和methodName就能创建想创建的类，调用想调用的方法（有局限性以后解决，例如不同包）
* 还有要记住libs包添加jar包后要右键让它变成lib类型文件夹。
*
*
*
*
*
* 以上带有Declared的说明可以获取私有的成员。但是要想访问它，还需要忽略访问量修饰符的安全检查
* 要访问的成员.setAccessible(true)
*
*
* */
public class 反射 {
}
